//
//  WYWRemotePlayer.m
//  WYWPlayer
//
//  Created by Mr.Run on 2017/11/9.
//  Copyright © 2017年 Mr.Run. All rights reserved.
//

#import "WYWRemotePlayer.h"
#import <AVFoundation/AVFoundation.h>
#import "WYWRemoteResourceLoaderDelegate.h"
#import "NSURL+Extension.h"

@interface WYWRemotePlayer ()
{
    BOOL _isUserPause;
}
@property (nonatomic,strong) AVPlayer *player;
@property (nonatomic,strong) WYWRemoteResourceLoaderDelegate *resourceLoaderDelegate;

@end

@implementation WYWRemotePlayer

static WYWRemotePlayer *_sharedInstance;
+(instancetype)sharedInstance{
    
    if (!_sharedInstance) {
        _sharedInstance = [[WYWRemotePlayer alloc]init];
    }
    return _sharedInstance;
}

+(instancetype)allocWithZone:(struct _NSZone *)zone{
    
    if (!_sharedInstance) {
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            _sharedInstance = [super allocWithZone:zone];
        });
    }
    return _sharedInstance;
}

-(void)playWithURL:(NSURL *)url isCache:(BOOL)isCache{
    
    NSURL *currentURL = [(AVURLAsset *)self.player.currentItem.asset URL];
    
    if ([url isEqual:currentURL] || [[url streamingURL] isEqual:currentURL]) {
        [self resume];
        return;
    }
    
    _url = url;
    
    if (isCache) {
        url = [url streamingURL];
    }
    
    AVURLAsset *asset = [AVURLAsset assetWithURL:url];
    if (self.player.currentItem) {
        [self removeObserver];
    }
    
    self.resourceLoaderDelegate = [WYWRemoteResourceLoaderDelegate new];
    [asset.resourceLoader setDelegate:self.resourceLoaderDelegate queue:dispatch_get_main_queue()];
    
    AVPlayerItem *item = [AVPlayerItem playerItemWithAsset:asset];
    
    [item addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];
    [item addObserver:self forKeyPath:@"playbackLikelyToKeepUp" options:NSKeyValueObservingOptionNew context:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playToEnd) name:AVPlayerItemDidPlayToEndTimeNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playInterrupt) name:AVPlayerItemPlaybackStalledNotification object:nil];
    self.player = [AVPlayer playerWithPlayerItem:item];
    
}

-(void)pause{
    [self.player pause];
    _isUserPause = YES;
    if (self.player) {
        self.state = WYWRemotePlayerStatePause;
    }
}
    
-(void)resume{
    [self.player play];
    _isUserPause = NO;
    if (self.player && self.player.currentItem.playbackLikelyToKeepUp) {
        self.state = WYWRemotePlayerStatePlaying;
    }
}
    
-(void)stop{
    [self.player pause];
    self.player = nil;
    if (self.player) {
        self.state = WYWRemotePlayerStateStopped;
    }
}
    
-(void)seekWithTimeDiffer:(NSTimeInterval)timeDiffer{
    
//    CMTime totalTime = self.player.currentItem.duration;
//    NSTimeInterval totalTimeSec = CMTimeGetSeconds(totalTime);
    NSTimeInterval totalTimeSec = [self totalTime];
//    CMTime playTime = self.player.currentItem.currentTime;
//    NSTimeInterval playTimeSec = CMTimeGetSeconds(playTime);
    NSTimeInterval playTimeSec = [self currentTime];
    playTimeSec += timeDiffer;
    
    [self seekWithProgress:playTimeSec/totalTimeSec];
}
    
-(void)seekWithProgress:(CGFloat)progress{
    
    if (progress < 0 || progress > 1) {
        return;
    }
    
    CMTime totalTime = self.player.currentItem.duration;
    
    NSTimeInterval totalSec = CMTimeGetSeconds(totalTime);
    NSTimeInterval playTimeSec = totalSec * progress;
    CMTime currentTime = CMTimeMake(playTimeSec, 1);
    [self.player seekToTime:currentTime completionHandler:^(BOOL finished) {
        if (finished) {
            NSLog(@"%s~~~%d~~~确定加载这个时间点的音频",__func__,__LINE__);
        }else{
            NSLog(@"%s~~~%d~~~取消这个时间点的音频",__func__,__LINE__);
        }
    }];
}
    
-(void)setRate:(CGFloat)rate{
    [self.player setRate:rate];
}

-(CGFloat)rate{
    return self.player.rate;
}

-(void)setMuted:(BOOL)muted{
    self.player.muted = muted;
}

-(BOOL)muted{
    return self.player.muted;
}

-(void)setVolume:(CGFloat)volume{
    if (volume < 0 || volume > 1) {
        return;
    }
    
    if (volume > 0) {
        [self setMuted:NO];
    }
    
    self.player.volume = volume;
}

-(CGFloat)volume{
    return self.player.volume;
}

-(NSTimeInterval)totalTime{
    CMTime totalTime = self.player.currentItem.duration;
    NSTimeInterval totalTimeSec = CMTimeGetSeconds(totalTime);
    if (isnan(totalTimeSec)) {
        totalTimeSec = 0;
    }
    return totalTimeSec;
}

-(NSString *)totalTimeFormat{
    return [NSString stringWithFormat:@"%02zd:%02zd",(int)self.totalTime/60, (int)self.totalTime%60];
}

-(NSString *)currentTimeFormat{
    return [NSString stringWithFormat:@"%02zd:%02zd",(int)self.currentTime/60, (int)self.currentTime%60];
}

-(NSTimeInterval)currentTime{
    CMTime playTime = self.player.currentItem.currentTime;
    NSTimeInterval playTimeSec = CMTimeGetSeconds(playTime);
    if (isnan(playTimeSec)) {
        playTimeSec = 0;
    }
    return playTimeSec;
}

-(CGFloat)progress{
    if (self.totalTime == 0) {
        return 0;
    }
    return self.currentTime/self.totalTime;
}

-(CGFloat)loadDataProgress{
    
    if (self.totalTime == 0) {
        return 0;
    }
    
    CMTimeRange timeRange = [[self.player.currentItem loadedTimeRanges].lastObject CMTimeRangeValue];
    CMTime loadTime = CMTimeAdd(timeRange.start, timeRange.duration);
    NSTimeInterval loadTimeSec = CMTimeGetSeconds(loadTime);
    return loadTimeSec/self.totalTime;
}

-(void)setState:(WYWRemotePlayerState)state{
    #warning TODO: 告诉外界状态
    _state = state;
}

-(void)playToEnd{
    NSLog(@"%s~~~%d~~~播放完成",__func__,__LINE__);
    self.state = WYWRemotePlayerStateStopped;
}

-(void)playInterrupt{
    NSLog(@"%s~~~%d~~~播放被打断",__func__,__LINE__);
    self.state = WYWRemotePlayerStatePause;
}

-(void)removeObserver{
    [self.player.currentItem removeObserver:self forKeyPath:@"status"];
    [self.player.currentItem removeObserver:self forKeyPath:@"playbackLikelyToKeepUp"];
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context{
    
    if ([keyPath  isEqual: @"status"]) {
        AVPlayerItemStatus status = [change[NSKeyValueChangeNewKey] integerValue];
        if (status == AVPlayerItemStatusReadyToPlay) {
            NSLog(@"%s~~~%d~~~资源准备好了, 这时候播放没有问题",__func__,__LINE__);
            [self resume];
        }else{
            NSLog(@"%s~~~%d~~~状态为知",__func__,__LINE__);
            self.state = WYWRemotePlayerStateFailed;
        }
    }else if([keyPath isEqualToString:@"playbackLikelyToKeepUp"]){
        BOOL ptk = [change[NSKeyValueChangeNewKey] integerValue];
        if (ptk) {
            NSLog(@"%s~~~%d~~~当前准备的资源足够播放了",__func__,__LINE__);
            if (!_isUserPause) {
                [self resume];
            }else{
                
            }
        }else{
            NSLog(@"%s~~~%d~~~资源不够播放了, 正在加载",__func__,__LINE__);
            self.state = WYWRemotePlayerStateLoading;
        }
    }
}
@end
